package edu.ptu.springboot04.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;

import javax.servlet.http.HttpServletRequest;
import java.util.Calendar;

/**
 * JWT令牌工具类，提供令牌生成、验证和解析功能
 *
 * @BelongsProject: springboot04
 * @BelongsPackage: edu.ptu.springboot04.utils
 * @Author: HYJ
 * @CreateTime: 2025-03-21  21:29
 * @Description: JWT工具类，包含以下功能：
 * 1. 生成带用户信息的JWT令牌
 * 2. 验证令牌有效性
 * 3. 从请求中解析用户信息
 * @Version: 1.0
 */
public class JWTUtil {
    // 密钥（建议通过配置注入）
    public static final String SECRET_KEY = "secret_key";
    // 令牌有效期（单位：天）
    public static final int EXPIRE_TIME = 10;
    // 用户ID声明字段
    public static final String USER_ID = "userId";
    // 用户名声明字段
    public static final String USER_NAME = "userName";

    /**
     * 生成JWT令牌
     *
     * @param userId   用户ID
     * @param userName 用户名
     * @return 包含以下声明的JWT令牌：
     * - audience: 固定值"http://localhost:8080"
     * - claims: 用户ID和用户名
     * - expiresAt: 当前时间+EXPIRE_TIME天
     */
    public static String generateToken(Long userId, String userName) {
        //获取过期时间
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, EXPIRE_TIME);

        //生成token
        return JWT.create()
                .withAudience("http://localhost:8080")
                .withClaim(USER_ID, userId)
                .withClaim(USER_NAME, userName)
                .withExpiresAt(calendar.getTime())
                .sign(Algorithm.HMAC256(SECRET_KEY));
    }

    /**
     * 验证JWT令牌有效性
     *
     * @param token 需要验证的令牌字符串
     * @return 验证结果 true-有效令牌 / false-无效令牌
     * @throws JWTVerificationException 当令牌格式错误或签名无效时抛出
     */
    public static boolean vetifyToken(String token) {

        // 尝试使用HMAC256算法和SECRET_KEY对token进行验证
        try {
            JWT.require(Algorithm.HMAC256(SECRET_KEY)).build().verify(token);
            // 如果验证成功，返回true
            return true;
        } catch (Exception e) {
            // 如果验证失败，返回false
            return false;
        }
    }

    /**
     * 从HTTP请求中解析用户名
     *
     * @param request HTTP请求对象
     * @return 用户名（从token的USER_NAME声明中提取）
     * @throws JWTDecodeException 当token不存在或格式错误时抛出
     */
    public static String getUserName(HttpServletRequest request) {
        // 解码请求头中的token
        return JWT.decode(request.getHeader("token")).getClaim(USER_NAME).asString();
    }

    /**
     * 从HTTP请求中解析用户ID
     *
     * @param request HTTP请求对象
     * @return 用户ID（从token的USER_ID声明中提取）
     * @throws JWTDecodeException 当token不存在或格式错误时抛出
     */
    public static Long getUserId(HttpServletRequest request) {
        // 解码请求头中的token
        return JWT.decode(request.getHeader("token")).getClaim(USER_ID).asLong();
    }
}